﻿using SBlogCore.Common.Snowflake;
using SBlogCore.Entitys.SysOrgManager;
using SBlogCore.WebAdminApplication.SysOrgManager.Dto;
using SBlogCore.WebAdminApplication.SysOrgManager.IServices;

namespace SBlogCore.WebAdminApplication.SysOrgManager.Serivices
{
    public class SysOrgInfoService: ISysOrgInfoService
    {
        private readonly IRepository<SysOrgInfo> _sysOrgInfoRepository;

        public SysOrgInfoService(IRepository<SysOrgInfo> sysOrgInfoRepository)
        {
            this._sysOrgInfoRepository = sysOrgInfoRepository;
        }
        /// <summary>
        /// 获取组织列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<SysOrgInfo>> GetSysOrgList()
        {
            Expression<Func<SysOrgInfo, bool>> expression = w=>true;
            List<SysOrgInfo> res = await _sysOrgInfoRepository
                .Where(expression)
                //.Include(w=>w.ChildrenList)
                .ToListAsync();
            return res.Where(w=>w.ParentInfo==null).ToList();
        }
        /// <summary>
        /// 通过ID获取数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<SysOrgInfo> GetSysOrgInfoById(long id)
        {
            var res= await _sysOrgInfoRepository.FirstOrDefaultAsync(w => w.Id == id);
            if (res==null)
            {
                throw SBlogCoreException.Say($"数据不存在！");
            }
            return res;
        }

        /// <summary>
        /// 组织信息保存
        /// </summary>
        /// <param name="inPut"></param>
        /// <returns></returns>
        public async Task AddSysOrgInfo(SysOrgInfoInPut inPut)
        {
            SysOrgInfo data = inPut.Adapt<SysOrgInfo>();
            data.Id= IDGenerator.NextId();
            data.LineNode = $"|{data.Id}";
            data.Level = 1;
            if (data.ParentInfoId.HasValue)
            {
                var parentInfo = await _sysOrgInfoRepository.FirstOrDefaultAsync(s=>s.Id==data.ParentInfoId.Value);
                if (parentInfo==null)
                    throw SBlogCoreException.Say($"父级ID{data.ParentInfoId.Value}不存在！");
                if (await _sysOrgInfoRepository.AnyAsync(s=>s.Code==inPut.Code))
                    throw SBlogCoreException.Say($"编码{inPut.Code}已存在！");
                data.Level = parentInfo.Level + 1;
                data.LineNode = $"|{parentInfo.Id}"+data.LineNode;
            }
            await _sysOrgInfoRepository.InsertAsync(data);
        }
        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="inPut"></param>
        /// <returns></returns>
        public async Task UpdateSysOrgInfo(SysOrgInfoEditInPut inPut)
        {
            SysOrgInfo? rowData = await _sysOrgInfoRepository.FirstOrDefaultAsync(s=>s.Id==inPut.Id!.Value);
            if (rowData==null)
                throw SBlogCoreException.Say($"Id为{inPut.Id}的数据不存在！");
            //编号发生变化的时候比较新的编号是否存在
            if (!inPut.Code!.Equals(rowData.Code))
            {
                if (await AnyCode(inPut.Code, inPut.Id!.Value))
                    throw SBlogCoreException.Say($"编码{inPut.Code}已存在！");
            }
            //父级发生变化时更新等级
            if (!inPut.ParentInfoId.Equals(rowData.ParentInfoId))
            {
                SysOrgInfo newParentInfo = await _sysOrgInfoRepository.FirstAsync(s => s.Id == inPut.ParentInfoId);
                rowData.Level = (newParentInfo.Level) + 1;
                rowData.LineNode = $"|{newParentInfo.Id}" + rowData.LineNode;
            }
            rowData.Name = inPut.Name;
            rowData.Code = inPut.Code;
            await _sysOrgInfoRepository.UpdateAsync(rowData);
            await UpdateSysOrgChildrenInfo(rowData);
        }

        private async Task UpdateSysOrgChildrenInfo(SysOrgInfo parentInfo)
        {
            var children = await _sysOrgInfoRepository.Where(w => w.ParentInfoId == parentInfo.Id).ToListAsync();
            foreach (var org in children)
            {
                org.LineNode = $"|{parentInfo.Id}" + org.LineNode;
                await UpdateSysOrgChildrenInfo(org);
                await _sysOrgInfoRepository.UpdateAsync(org);
            }
        }

        /// <summary>
        /// 判断编号是否存在
        /// </summary>
        /// <param name="id"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public async Task<bool> AnyCode(string code, long? id = null)
        {
            Expression<Func<SysOrgInfo, bool>> expression = s => s.Code == code;
            if (id.HasValue)
            {
                expression = expression.And(s => s.Id != id);
            }
            return await _sysOrgInfoRepository.AnyAsync(expression);
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>

        public async Task<int> DeleteSysOrgInfo(List<long> ids)
        {
          return await _sysOrgInfoRepository.ExecuteDeleteAsync(w=>ids.Contains(w.Id));
        }
    }
}
